<?php

/**
 *	IFXField Class
 *	@package IntuiFormX
 *	@author Jeremy Clifton <j.clifton@intuiworx.com>
 *	@version 4.0.6 (2007-08-30)
 */
class IFXField
{

	/** 
	 *	CHECKBOX ONLY: The value that the generated checkbox will pass if it is checked. 
	 *	@access private
	 *	@private string
	 */	
	private $checkedVal	= null;
	
	/** 
	 *	TEXTAREA ONLY: The number of columns the generated textarea will display.
	 *	@access private
	 *	@private int
	 */
	private $cols = null;
	
	/**
	 *	The element's class.
	 *	@access private
	 *	@private string
	 */
	private $class = null;
	
	/** 
	 *	An array of name/value pairs represeting CSS properties for the generated form field. 
	 *	@access private
	 *	@private array
	 */
	private $css = array();	
	
	/** 
	 *	The current value of the generated form field. Can be an array for select/dropdowns.
	 *	@access private
	 *	@private string 
	 */
	private $currentVal = null;				
	
	/** 
	 *	The default value of the generated form field (if $currentVal isn't set). 
	 *	@access private
	 *	@private string (or array for SELECT)
	 */
	private $defaultVal = null;
	
	/**
	 *	Determines if the field is disabled or not.
	 *	@access private
	 *	@private boolean
	 */
	private $disabled = false;
	
	/**
	 *	Keeps track of which field group this field is a member of.
	 *	@access private
	 *	@private string
	 */
	private $fieldGroup = null;
	
	/**
	 *	Keeps track of which fieldset this field is a member of.
	 *	@access private
	 *	@private string
	 */
	private $fieldSet = null;
	
	/**
	 *	Reference to the form object that this is being added to.
	 *	@access private
	 *	@private IntuiForm object
	 */
	private $fObj = null;
	
	/** 
	 *	An array of name/value pairs representing event handlers for the generated form field. 
	 *	@access private
	 *	@private array
	 */
	private $handlers = array();
	
	/**
	 *	The field's DOM id.
	 *	@access private
	 *	@private string
	 */
	private $id = null;
	
	/**
	 *	Indicates if this field is required for processing (this is solely for helping form validation in PHP).
	 *	@access private
	 *	@private boolean
	 */
	private $isRequired = false;
	
	/** 
	 *	Label for the form field.
	 *	@access private
	 *	@private string 
	 */
	private $label = null;
	
	/**
	 *	Label class(es).
	 *	@access private
	 *	@private string
	 */
	private $labelClass = null;
	
	/** 
	 *	TEXT, PASSWORD ONLY: The length (in characters) of the generated textbox.
	 *	@access private
	 *	@private int 
	 */
	private $len = null;						
	
	/** 
	 *	TEXT, PASSWORD ONLY: The maximum number of characters the generated textbox will accept as input. 
	 *	@access private
	 *	@private int
	 */
	private $maxLen = null;					
	
	/** 
	 *	SELECT ONLY: Indicates that the generated select will display multiple lines of input.
	 *
	 *	@access private
	 *	@private boolean 
	 */
	private $multi = null;						
	
	/** 
	 *	SELECT ONLY: The number of lines of options that the generated select will display.
	 *	@access private
	 *	@private int 
	 */
	private $multiSize = null;					
	
	/** 
	 *	The id/name for the generated form field. 
	 *	@access private
	 *	@private string
	 */
	private $name = null;
	
	/**
	 *	SELET ONLY. The array holding the options and option groups.
	 *	@access private
	 *	@private array
	 */
	private $optArray = array();
	
	/**
	 *	Stores the level of indentation for select options.
	 *	@access private
	 *	@private int
	 */
	private $optIndent = 0;
	
	/** 
	 *	TEXTAREA ONLY: The number of rows the generated textarea will display.
	 *	@access private
	 *	@private int 
	 */
	private $rows = null;
	
	/**
	 *	The type of field this object represents.
	 *	@access private
	 *	@private string
	 */
	private $type = null;
	
	/** 
	 *	SELECT ONLY: An array of name/value pairs that represent possible values for the generated select.
	 *	@access private
	 *	@private array 
	 */
	private $vals = array();					
	
	/**
	 *	IntuiFormField constructor. Creates a new form field.
	 *	@param object $formObj
	 *	@param string $id -- The DOM id that will be assigned to this form field.
	 *	@param string $type -- One of: button, checkbox, file, hidden, password, radio
	 *		select, submit, text, or textarea.
	 *	@return object -- The IntuiFormField object.
	 */
	public function __construct($formObj, $id, $type)
	{
		$this->fObj	= $formObj;
		$this->id = $id;
		$this->name = $id;
		$this->type = $type;
	}
	
	/**
	 *	Builds the form field from the passed XML data.
	 *	@param object $f - IntuiFormX object
	 *	@param string $xml
	 */
	public function buildFromXML($f, $xml)
	{
		
		$sx = simplexml_load_string($xml);
		
		$disabled = ((string)$sx['disabled'] == 'Y')?true:false;
		$required = ((string)$sx['required'] == 'Y')?true:false;
		
		$fld = $f->addField((string)$sx['id'], (string)$sx['type']);
		$fld->setCheckedVal((string)$sx->checkedVal);
		$fld->setClass((string)$sx['class']);
		$fld->setCols((string)$sx['cols']);
		$fld->setRows((string)$sx['rows']);
		$fld->setCurrentVal((string)$sx->currentVal);
		$fld->setDefaultVal((string)$sx->defaultVal);
		$fld->setDisabled($disabled);
		$fld->setIsRequired($required);
		$fld->setLabel((string)$sx->label);
		$fld->setLabelClass((string)$sx->label['class']);
		$fld->setLen((int)$sx['len']);
		$fld->setMaxLen((int)$sx['maxlen']);
		$fld->setMulti( (strtolower($sx['multi']) == 'y') ? true : false );
		$fld->setMultiSize((int)$sx['multisize']);
		if ((string)$sx['name'] != '') {
			$fld->setName((string)$sx['name']);
		}
		foreach ($sx->css as $c) {
			$fld->setCSS((string)$c['name'], (string)$c['value']);
		}
		foreach ($sx->handler as $h) {
			$fld->setHandler((string)$h['name'], (string)$h['value']);
		}
		if (sizeof($sx->options->option) > 0) {
			foreach ($sx->options->option as $o) {
				$fld->optArray[] = array('label' => (string)$o['label'], 'value' => (string)$o['value']);
			}
		}
		return $fld;
		
	}
	
	/**
	 *	Retrieves the array of CSS stuff.
	 *	@return array
	 */
	public function getCSSArray() { return $this->css; }
	
	/**
	 *	Retrieves a CSS property value for a particular IntuiFormField object.
	 *	@param string $prop -- The property name
	 *	@return string -- The property value.
	 */
	public function getCSS($prop) { return $this->css[$prop]; }
	
	/**
	 *	Retrieves the field's DOM id.
	 *	@return string
	 */
	public function getID() { return $this->id; }
	
	/**
	 *	Retrieves the field label.
	 *	@return string
	 */
	public function getLabel()
	{
		if ($this->isRequired()) {
			if ($this->labelClass) {
				$classes = ' '.$this->labelClass;
			}
			return '<label id="lbl-'.$this->id.'" class="IFX_Required '.$classes.'" for="'.$this->name.'">'.$this->label.'</label>';
		} else {
			if ($this->labelClass) {
				$classes = 'class="'.$this->labelClass.'"';
			}
			return '<label id="lbl-'.$this->id.'" for="'.$this->name.'"'.$classes.'>'.$this->label.'</label>';
		}
	}
	
	/**
	 *	Retrieves an element property value for a particular IntuiFormField object.
	 *	@access public
	 *	@param string $handler -- The handler name.
	 *	@return string -- The handler's value.
	 */
	public function getHandler($handler) { return $this->handlers[$handler]; }
	
	/**
	 *	Retrieves the set handlers for this element.
	 *	@access public
	 *	@return array
	 */
	public function getHandlerArray() { return $this->handlers; }
	
	/**
	 *	Indicates if this form field is set as being required.
	 *	@return boolean
	 */
	public function isRequired() { return $this->isRequired; }
	
	/**
	 *	Generates HTML code for this form field.
	 *	@access public
	 *	@return string -- HTML Code.
	 */
	public function render()
	{
		// If the currentVal property isn't set, and a default value exists, use it.
		if ($this->currentVal == null AND $this->defaultVal != null) {
			$this->currentVal	= $this->defaultVal;
		}
		$method					= '_'.$this->type;
		if (method_exists($this, $method)) {
			return $this->$method();
		}
	}
	
	/**
	 *	Sets the checked value (checkbox only)
	 *	@param string $val
	 */
	public function setCheckedVal($val) { $this->checkedVal = $val; }
	
	/**
	 *	Sets the element's class.
	 *	@param string $val
	 */
	public function setClass($val) { $this->class = $val; }
	
	/**
	 *	Sets a CSS property for this form field.
	 *	@access public
	 *	@param string $prop -- The property name.
	 *	@param string $val -- The property's value.
	 */
	public function setCSS($prop, $val) { $this->css[$prop] = $val; }
	
	/**
	 *	Sets the number of this columns (textarea only).
	 *	@access public
	 *	@param string $val
	 */
	public function setCols($val) { $this->cols = $val; }
	
	/**
	 *	Sets the current value of this field.
	 *	@access public
	 *	@param mixed $val
	 */
	public function setCurrentVal($val) 
	{ 
		if ($this->type != 'select' and is_array($val)) {
			trigger_error('Cannot assign multiple default values to '.$this->type.' ('.$this->name.') fields!', E_USER_ERROR);
			exit;
		}
		$this->currentVal 	= $val; 
	}
	
	/**
	 *	Sets the default value of this field.
	 *	@access public
	 *	@param mixed $val
	 */
	public function setDefaultVal($val) 
	{ 
		if ($this->type != 'select' and is_array($val)) {
			trigger_error('Cannot assign multiple default values to '.$this->type.' ('.$this->name.') fields!', E_USER_ERROR);
			exit;
		}
		$this->defaultVal 	= $val; 
	}
	
	/**
	 *	Sets the disabled status of this field.
	 *	@access public
	 *	@param mixed $val
	 */
	public function setDisabled($val) { $this->disabled = (bool)$val; }
	
	/**
	 *	Sets an element event handler for this form field.
	 *	@access public
	 *	@param string $handler -- The event handler name.
	 *	@param string $val -- The event handler value.
	 */
	public function setHandler($handler, $val) { $this->handlers[$handler]	= $val; }
	
	/**
	 *	Sets the is-required value of this field.
	 *	@access public
	 *	@param boolean $val
	 */
	public function setIsRequired($val) { $this->isRequired = $val; }
	
	/**
	 *	Sets the label for this form field
	 *	@access public
	 *	@param string $val
	 */
	public function setLabel($val) { $this->label = $val; }
	
	/**
	 *	Sets the label class for this form field
	 *	@access public
	 *	@param string $val
	 */
	public function setLabelClass($val) { $this->labelClass = $val; }
	
	/**
	 *	Sets the field length (text only)
	 *	@access public
	 *	@param int $val
	 */
	public function setLen($val) { $this->len = $val; }
	
	/**
	 *	Sets the maximum field length (text only)
	 *	@access public
	 *	@param int $val
	 */
	public function setMaxLen($val) { $this->maxLen = $val; }
	
	/**
	 *	Is this a multi select?
	 *	@access public
	 *	@param mixed $val
	 */
	public function setMulti($val) { $this->multi = (bool)$val; }
	
	/**
	 *	Sets the number of lines for a multi select box.
	 *	@access public
	 *	@param int $val
	 */
	public function setMultiSize($val) { $this->multiSize = $val; }
	
	/**
	 *	Sets the name for this field.
	 *	@param string $val
	 */
	public function setName($val) { $this->name = $val; }
	
	/**
	 *	Sets the options and option groups for a select box. Setting the values
	 *	with this function will override and clear any values set via setVals().
	 *	@param array $optArray
	 */
	public function setOptions($optArray = array()) { $this->optArray = $optArray; }
	
	/**
	 *	Sets the number of rows (textarea only)
	 *	@access public
	 *	@param int $val
	 */
	public function setRows($val) { $this->rows = $val; }
	
	/**
	 *	Generates a HTML button.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _button()
	{
	
		// Generate the submit button
		$element				.= "\n";
		$element				.= "<!-- *** Button Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="button" id="'.$this->id.'" value="'.$this->label.'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Button Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML checkbox.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _checkbox()
	{
		
		// Create the checkbox
		$element				.= "\n";
		$element				.= "<!-- *** Checkbox Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="checkbox" id="'.$this->id.'" name="'.$this->name.'" value="'.$this->checkedVal.'"';
		if ($this->checkedVal == $this->currentVal) {
			$element			.= ' checked="checked"';
		}
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Checkbox Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML file input.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _file()
	{
	
		// Create the file field
		$element				.= "\n";
		$element				.= "<!-- *** File Field Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="file" id="'.$this->id.'" name="'.$this->name.'" size="'.$this->len.'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated File Field Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML hidden input.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _hidden()
	{
	
		// Create the hidden field
		$element				.= "\n";
		$element				.= "<!-- *** Hidden Field Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="hidden" id="'.$this->id.'" name="'.$this->name.'" value="'.$this->currentVal.'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Hidden Field Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML password textbox.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _password()
	{
	
		// Create the password field
		$element				.= "\n";
		$element				.= "<!-- *** Password Field Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="password" id="'.$this->id.'" name="'.$this->name.'" size="'.$this->len.'" maxlength="'.$this->maxLen.'" ';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Password Field Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML radio button.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _radio()
	{
	
		// Create the radio button
		$element				.= "\n";
		$element				.= "<!-- *** Radio Button Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="radio" id="'.$this->id.'" name="'.$this->name.'" value="'.$this->checkedVal.'"';
		if ($this->checkedVal == $this->currentVal) {
			$element			.= ' checked="checked"';
		}
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Radio Button Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML select/dropdown.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _select()
	{
		
		// If this is a multiple select, we need to change the id.
		if ($this->multi) { $this->name	 = $this->name.'[]'; }
	
		// Create the select
		$element .= "\n";
		$element .= "<!-- *** Select Button Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element .= '<select id="'.$this->id.'" name="'.$this->name.'"';
		if ($this->multi) {
			$element .= ' multiple="multiple"';
		}
		if ($this->multiSize > 1) {
			$element .= ' size="'.$this->multiSize.'"';
		}
		if ($this->class) {
			$element .= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element .= ' disabled="disabled"';
		}
		$element .= ' >'."\n";
		$element .= $this->_selectOptions($this->optArray);
		$element .= "</select>\n";
		$element .= "<!-- *** End Generated Select Code *** -->\n";
		$element .= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Allows us to recursively create option groups in a select.
	 *	@param array $options
	 *	@return string
	 */
	private function _selectOptions($options)
	{
	
		$this->optIndent++;
		foreach ($options as $id => $arr) {
			// Check for option groups
			if ($arr['type'] == 'optionGroup') {
				for ($i = 1; $i <= $this->optIndent; $i++) {
					$opts	.= "\t";
				}
				$opts		.= '<optgroup label="'.$arr['label'].'"';
				if ($arr['id']) {
					$opts	.= ' id="'.$arr['id'].'"';
				}
				if ($arr['disabled']) {
					$opts	.= ' disabled="disabled"';
				}
				$opts		.= ">\n";
				$opts		.= $this->_selectOptions($arr['content']);
				for ($i = 1; $i <= $this->optIndent; $i++) {
					$opts	.= "\t";
				}
				$opts		.= "</optgroup>\n";
			} else {
				for ($i = 1; $i <= $this->optIndent; $i++) {
					$opts	.= "\t";
				}
				$opts		.= '<option value="'.$arr['value'].'"';
				if ( (is_array($this->currentVal) and in_array($arr['value'], $this->currentVal)) or $this->currentVal == $arr['value'] ) {
					$opts	.= ' selected="selected"';
				}
				if ($arr['id']) {
					$opts	.= ' id="'.$arr['id'].'"';
				}
				if ($arr['disabled']) {
					$opts	.= ' disabled="disabled"';
				}
				$opts		.= ">".$arr['label']."</option>\n";
			}
		}
		$this->optIndent--;
		return $opts;
	
	}
	
	/**
	 *	Generates a HTML submit button.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _submit()
	{
	
		// Generate the submit button
		$element				.= "\n";
		$element				.= "<!-- *** Submit Button Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="submit" id="'.$this->id.'" name="'.$this->name.'" value="'.$this->label.'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Submit Button Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML textbox.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _text()
	{
	
		// Create the text box
		$element				.= "\n";
		$element				.= "<!-- *** Text Box Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<input type="text" id="'.$this->id.'" name="'.$this->name.'" size="'.$this->len.'"';
		$element				.= ' maxlength="'.$this->maxLen.'" value="'.htmlentities($this->currentVal).'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= " />\n";
		$element				.= "<!-- *** End Generated Text Box Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
	/**
	 *	Generates a HTML textarea input.
	 *	@access private
	 *	@return string -- HTML code.
	 */
	private function _textarea()
	{
	
		// Create the textarea
		$element				.= "\n";
		$element				.= "<!-- *** Textarea Generated by IntuiFormX for PHP (http://www.intuiworx.com/software/IntuiFormX) *** -->\n";
		$element				.= '<textarea id="'.$this->id.'" name="'.$this->name.'" rows="'.$this->rows.'" cols="'.$this->cols.'"';
		if ($this->class) {
			$element			.= ' class="'.$this->class.'"';
		}
		if ($this->disabled) {
			$element			.= ' disabled="disabled"';
		}
		$element				.= ">".htmlentities($this->currentVal)."</textarea>\n";
		$element				.= "<!-- *** End Generated Textarea Code *** -->\n";
		$element				.= "\n";
		
		return $element;
	
	}
	
}

?>